import sys
import os
# Shared resources
BASE_RESOURCE_PATH = os.path.join( os.getcwd(), "resources" )
sys.path.append( os.path.join( BASE_RESOURCE_PATH, "lib" ) )
# append the proper platforms folder to our path, xbox is the same as win32
env = ( os.environ.get( "OS", "win32" ), "win32", )[ os.environ.get( "OS", "win32" ) == "xbox" ]
sys.path.append( os.path.join( BASE_RESOURCE_PATH, "platform_libraries", env ) )

import random,xbmcplugin,xbmcgui,hashlib, datetime, time, urllib,urllib2, elementtree.ElementTree as ET

try:
    # new XBMC 10.05 addons:
    import xbmcaddon
except ImportError:
    # old XBMC - create fake xbmcaddon module with same interface as new XBMC 10.05
    class xbmcaddon:
        """ fake xbmcaddon module """
        __version__ = "(old XBMC)"
        class Addon:
            """ fake xbmcaddon.Addon class """
            def __init__(self, id):
                self.id = id

            def getSetting(self, key):
                return xbmcplugin.getSetting(key)

            def setSetting(self, key, value):
                xbmcplugin.setSetting(key, value)

            def openSettings(self, key, value):
                xbmc.openSettings()

            def getLocalizedString(self, id):
                return xbmc.getLocalizedString(id)

ampache = xbmcaddon.Addon("plugin.music.ampache")

def addLink(name,url,iconimage,node):
        ok=True
        liz=xbmcgui.ListItem(name, iconImage=iconimage, thumbnailImage=iconimage)
        liz.setInfo( type="Music", infoLabels={ "Title": node.findtext("title"), "Artist": node.findtext("artist"), "Album": node.findtext("album"), "TrackNumber": str(node.findtext("track")) } )
        ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=url,listitem=liz)
        return ok

def addLinks(elem):
        ok=True
        li=[]
        for node in elem:
            liz=xbmcgui.ListItem(node.findtext("title").encode("utf-8"), iconImage=node.findtext("art"), thumbnailImage=node.findtext("art"))
            liz.setInfo( type="Music", infoLabels={ "Title": node.findtext("title").encode("utf-8"), "Artist": node.findtext("artist"), "Album": node.findtext("album"), "ReleaseDate": str(node.findtext("year")) } )
            tu= (node.findtext("url"),liz)
            li.append(tu)
        ok=xbmcplugin.addDirectoryItems(handle=int(sys.argv[1]),items=li,totalItems=len(elem))
        return ok

def addDir(name,object_id,token,mode,iconimage):
        xbmc.log(name,xbmc.LOGNOTICE)
        u=sys.argv[0]+"?object_id="+str(object_id)+"&mode="+str(mode)+"&name="+urllib.quote_plus(name)+"&token="+token
        ok=True
        liz=xbmcgui.ListItem(name, iconImage="DefaultFolder.png", thumbnailImage=iconimage)
        liz.setInfo( type="Music", infoLabels={ "Title": name } )
        ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=liz,isFolder=True)
        return ok
    
def addAlbumDir(name,object_id,token,mode,iconimage,elem):
        xbmc.log(name,xbmc.LOGNOTICE)
        artist_elem = elem.find("artist")
	artist_id = int(artist_elem.attrib["id"]) 
        cm = []
        cm.append( ( "Show all albums from artist", "XBMC.Container.Update(%s?object_id=%s&mode=2&token=%s)" % ( sys.argv[0],artist_id, token ) ) )
        u=sys.argv[0]+"?object_id="+str(object_id)+"&mode="+str(mode)+"&name="+urllib.quote_plus(name)+"&token="+token
        ok=True
        liz=xbmcgui.ListItem(name, iconImage="DefaultFolder.png", thumbnailImage=iconimage)
        liz.setInfo( type="Music", infoLabels={ "Title": name } )
        liz.addContextMenuItems(cm)
        ok=xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=liz,isFolder=True)
        return ok

def get_params():
        param=[]
        paramstring=sys.argv[2]
        if len(paramstring)>=2:
                params=sys.argv[2]
                cleanedparams=params.replace('?','')
                if (params[len(params)-1]=='/'):
                        params=params[0:len(params)-2]
                pairsofparams=cleanedparams.split('&')
                param={}
                for i in range(len(pairsofparams)):
                        splitparams={}
                        splitparams=pairsofparams[i].split('=')
                        if (len(splitparams))==2:
                                param[splitparams[0]]=splitparams[1]
                                
        return param
    
def getFilterFromUser():
        loop = True
        while(loop):
                kb = xbmc.Keyboard('', '', True)
                kb.setHeading('Enter Search Filter')
                kb.setHiddenInput(False)
                kb.doModal()
                if (kb.isConfirmed()):
                        filter = kb.getText()
                        loop = False
                else:
                        return(False)
        return(filter)

def AMPACHECONNECT():
    myTimeStamp = str(int(time.time()))
    sdf = ampache.getSetting("password")
    myKey = hashlib.sha256(ampache.getSetting("password")).hexdigest()
    myPassphrase = hashlib.sha256(myTimeStamp + myKey).hexdigest()
    myURL = ampache.getSetting("server") + 'server/xml.server.php?action=handshake&auth='
    myURL += myPassphrase + "&timestamp=" + myTimeStamp
    myURL += '&version=350001&user=' + ampache.getSetting("username")
    xbmc.log(myURL,xbmc.LOGNOTICE)
    req = urllib2.Request(myURL)
    response = urllib2.urlopen(req)
    tree=ET.parse(response)
    response.close()
    elem = tree.getroot()
    token = elem.findtext('auth')
    api = elem.findtext('api')
    update = elem.findtext('update')
    add = elem.findtext('add')
    clean = elem.findtext('clean')
    songs = elem.findtext('songs')
    albums = elem.findtext('albums')
    artists = elem.findtext('artists')
    playlists = elem.findtext('playlists')
    videos = elem.findtext('videos')
    return elem

def GETARTISTS(token,limit=50,offset=0,add=None,filter=None,exact=None):
    xbmcplugin.setContent(int(sys.argv[1]), 'artists')
    thisURL = build_ampache_url(token,"artists",filter=filter,add=add)
    
    req = urllib2.Request(thisURL)
    response = urllib2.urlopen(req)
    tree=ET.parse(response)
    response.close()
    elem = tree.getroot()
    if elem.findtext("error"):
        errornode = elem.find("error")
        if errornode.attrib["code"]=="401":
            elem = AMPACHECONNECT()
            token = elem.findtext("auth")
            thisURL = build_ampache_url(token,"artists",filter=filter)
            req = urllib2.Request(thisURL)
            response = urllib2.urlopen(req)
            tree=ET.parse(response)
            response.close()
            elem = tree.getroot()
    for node in elem:
        addDir(node.findtext("name").encode("utf-8"),node.attrib["id"],token,2,"DefaultFolder.png")

def GETALBUMS(token,objectid=None,filter=None,add=None,limit=5000,offset=0):
    xbmcplugin.setContent(int(sys.argv[1]), 'albums')
    if filter:
        action = 'albums'
    elif objectid:
        action = 'artist_albums'
        filter = objectid
    else:
        action = 'albums'
    thisURL = build_ampache_url(token,action,filter=filter,add=add)

    req = urllib2.Request(thisURL)
    response = urllib2.urlopen(req)
    tree=ET.parse(response)
    response.close()
    elem = tree.getroot()
    if elem.findtext("error"):
        errornode = elem.find("error")
        if errornode.attrib["code"]=="401":
            elem = AMPACHECONNECT()
            token = elem.findtext("auth")
            thisURL = build_ampache_url(token,action,filter=filter)
            req = urllib2.Request(thisURL)
            response = urllib2.urlopen(req)
            tree=ET.parse(response)
            response.close()
            elem = tree.getroot()
    for node in elem:
        addAlbumDir(node.findtext("name").encode("utf-8"),node.attrib["id"],token,3,node.findtext("art"),node)

def GETSONGS(token,objectid=None,filter=None,add=None,limit=5000,offset=0):
    xbmcplugin.setContent(int(sys.argv[1]), 'songs')
    if filter:
        action = 'songs'
    elif objectid:
        action = 'album_songs'
        filter = objectid
    else:
        action = 'songs'
        
    thisURL = build_ampache_url(token,action,filter=filter,add=add)
    req = urllib2.Request(thisURL)
    response = urllib2.urlopen(req)
    tree=ET.parse(response)
    response.close()
    elem = tree.getroot()
    if elem.findtext("error"):
        errornode = elem.find("error")
        if errornode.attrib["code"]=="401":
            elem = AMPACHECONNECT()
            token = elem.findtext("auth")
            thisURL = build_ampache_url(token,action,filter=filter)
            req = urllib2.Request(thisURL)
            response = urllib2.urlopen(req)
            tree=ET.parse(response)
            response.close()
            elem = tree.getroot()
    addLinks(elem)
#    for node in elem:
#        addLink(node.findtext("title").encode("utf-8"),node.findtext("url"),node.findtext("art"),node)

def build_ampache_url(token,action,filter=None,add=None,limit=5000,offset=0):
    thisURL = ampache.getSetting("server") + 'server/xml.server.php?action=' + action 
    thisURL += '&auth=' + token
    thisURL += '&limit=' +str(limit)
    thisURL += '&offset=' +str(offset)
    if filter:
        thisURL += '&filter=' +urllib.quote_plus(str(filter))
    if add:
        thisURL += '&add=' + add
    return thisURL

def get_random_albums(token):
    xbmcplugin.setContent(int(sys.argv[1]), 'albums')
    elem = AMPACHECONNECT()
    token = elem.findtext('auth')
    albums = int(elem.findtext('albums'))
    random_albums = (int(ampache.getSetting("random_albums"))*3)+3
    seq = random.sample(xrange(albums),random_albums)
    for album_id in seq:
        thisURL = build_ampache_url(token,'albums',offset=album_id,limit=1)
	req = urllib2.Request(thisURL)
	response = urllib2.urlopen(req)
	tree=ET.parse(response)
	response.close()
	elem = tree.getroot()
	if elem.findtext("error"):
	    errornode = elem.find("error")
	    if errornode.attrib["code"]=="401":
	        elem = AMPACHECONNECT()
	        token = elem.findtext("auth")
	        thisURL = build_ampache_url(token,action,filter=filter)
	        req = urllib2.Request(thisURL)
	        response = urllib2.urlopen(req)
	        tree=ET.parse(response)
	        response.close()
	        elem = tree.getroot()
	for node in elem:
            fullname = node.findtext("name").encode("utf-8")
            fullname += " - "
            fullname += node.findtext("artist").encode("utf-8")
	    addAlbumDir(fullname,node.attrib["id"],token,3,node.findtext("art"),node)        


params=get_params()
name=None
mode=None
object_id=None
token=None

try:
        token=params["token"]
except:
        pass
try:
        name=urllib.unquote_plus(params["name"])
except:
        pass
try:
        mode=int(params["mode"])
except:
        pass
try:
        object_id=int(params["object_id"])
except:
        pass

print "Mode: "+str(mode)
print "Name: "+str(name)
print "ObjectID: "+str(object_id)

if mode==None:
        print ""
        elem = AMPACHECONNECT()
        token = elem.findtext("auth")

        addDir("Search...",0,token,4,"DefaultFolder.png")
        addDir("Recent...",0,token,5,"DefaultFolder.png")
        addDir("Random...",0,token,7,"DefaultFolder.png")
        addDir("Artists (" + str(elem.findtext("artists")) + ")",None,token,1,"DefaultFolder.png")
        addDir("Albums (" + str(elem.findtext("albums")) + ")",None,token,2,"DefaultFolder.png")
        #addDir("Search Artists...",99999,token,1,"DefaultFolder.png")
        #addDir("Search Albums...",99999,token,2,"DefaultFolder.png")
        #addDir("Search Songs...",99999,token,3,"DefaultFolder.png")

elif mode==1:
    if object_id == 99999:
        thisFilter = getFilterFromUser()
        if thisFilter:
            GETARTISTS(token, filter=thisFilter)
    elif object_id == 99998:
        elem = AMPACHECONNECT()
        token = elem.findtext("auth")
        update = elem.findtext("add")        
        xbmc.log(update[:10],xbmc.LOGNOTICE)
        GETARTISTS(token, add=update[:10])
    elif object_id == 99997:
        d = datetime.date.today()
        dt = datetime.timedelta(days=-7)
        nd = d + dt
        GETARTISTS(token, add=nd.isoformat())
    elif object_id == 99996:
        d = datetime.date.today()
        dt = datetime.timedelta(days=-30)
        nd = d + dt
        GETARTISTS(token, add=nd.isoformat())
    elif object_id == 99995:
        d = datetime.date.today()
        dt = datetime.timedelta(days=-90)
        nd = d + dt
        GETARTISTS(token, add=nd.isoformat())
    else:
        GETARTISTS(token)
       
elif mode==2:
        print ""
        if object_id == 99999:
            thisFilter = getFilterFromUser()
            if thisFilter:
                GETALBUMS(token, filter=thisFilter)
        elif object_id == 99998:
            elem = AMPACHECONNECT()
            token = elem.findtext("auth")
            update = elem.findtext("add")        
            xbmc.log(update[:10],xbmc.LOGNOTICE)
            GETALBUMS(token, add=update[:10])
        elif object_id == 99997:
            d = datetime.date.today()
            dt = datetime.timedelta(days=-7)
            nd = d + dt
            GETALBUMS(token, add=nd.isoformat())
        elif object_id == 99996:
            d = datetime.date.today()
            dt = datetime.timedelta(days=-30)
            nd = d + dt
            GETALBUMS(token, add=nd.isoformat())
        elif object_id == 99995:
            d = datetime.date.today()
            dt = datetime.timedelta(days=-90)
            nd = d + dt
            GETALBUMS(token, add=nd.isoformat())
        elif object_id:
            GETALBUMS(token, objectid=object_id)
        else:
            GETALBUMS(token)
        
elif mode==3:
        print ""
        if object_id == 99999:
            thisFilter = getFilterFromUser()
            if thisFilter:
                GETSONGS(token, filter=thisFilter)
        elif object_id == 99998:
            elem = AMPACHECONNECT()
            token = elem.findtext("auth")
            update = elem.findtext("add")        
            xbmc.log(update[:10],xbmc.LOGNOTICE)
            GETSONGS(token, add=update[:10])
        elif object_id == 99997:
            d = datetime.date.today()
            dt = datetime.timedelta(days=-7)
            nd = d + dt
            GETSONGS(token, add=nd.isoformat())
        elif object_id == 99996:
            d = datetime.date.today()
            dt = datetime.timedelta(days=-30)
            nd = d + dt
            GETSONGS(token, add=nd.isoformat())
        elif object_id == 99995:
            d = datetime.date.today()
            dt = datetime.timedelta(days=-90)
            nd = d + dt
            GETSONGS(token, add=nd.isoformat())
        else:
            GETSONGS(token, objectid=object_id)

elif mode==4:
    addDir("Search Artists...",99999,token,1,"DefaultFolder.png")
    addDir("Search Albums...",99999,token,2,"DefaultFolder.png")
    addDir("Search Songs...",99999,token,3,"DefaultFolder.png")

elif mode==5:
    addDir("Recent Artists...",99998,token,6,"DefaultFolder.png")
    addDir("Recent Albums...",99997,token,6,"DefaultFolder.png")
    addDir("Recent Songs...",99996,token,6,"DefaultFolder.png")

elif mode==6:
    addDir("Last Update",99998,token,99999-object_id,"DefaultFolder.png")
    addDir("1 Week",99997,token,99999-object_id,"DefaultFolder.png")
    addDir("1 Month",99996,token,99999-object_id,"DefaultFolder.png")
    addDir("3 Months",99995,token,99999-object_id,"DefaultFolder.png")

elif mode==7:
    addDir("Refresh...",0,token,7,"DefaultFolder.png")
    get_random_albums(token)

xbmcplugin.endOfDirectory(int(sys.argv[1]))
